package com.jackrain.nea.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jackrain.nea.config.Resources;
import com.jackrain.nea.core.query.ColumnLink;
import com.jackrain.nea.core.schema.*;
import com.jackrain.nea.core.web.interpreter.ColumnInterpreter;
import com.jackrain.nea.core.webaction.WebAction;
import com.jackrain.nea.exception.NDSException;
import com.jackrain.nea.util.PairTable;
import com.jackrain.nea.util.Tools;
import com.jackrain.nea.util.Validator;
import com.jackrain.nea.web.query.*;
import com.jackrain.nea.web.security.Directory;
import com.jackrain.nea.web.security.SecurityWebUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;


@Component
@Slf4j
public class ObjectSingle {


    public JSONObject getCommandforTableId(Table table, int perm,boolean ismaintable) {

        /**------check permission---**/
        boolean isWriteEnabled = (((perm & 3) == 3));
        boolean isSubmitEnabled = (((perm & 5) == 5));
        boolean isUnSubmitEnabled = (((perm & 9) == 9));
        boolean canUNsubmit=table.isActionEnabled(Table.UNSUBMIT)&&isUnSubmitEnabled;
        boolean canVoid = table.isActionEnabled(Table.VOID) && isWriteEnabled;
        boolean canExport = (((perm & 17) == 17));
        boolean canDelete = table.isActionEnabled(Table.DELETE) && isWriteEnabled;
        boolean canAdd = table.isActionEnabled(Table.ADD) && isWriteEnabled;
        boolean canModify = table.isActionEnabled(Table.MODIFY) && isWriteEnabled;
        boolean canSubmit = table.isActionEnabled(Table.SUBMIT) && isSubmitEnabled&&ismaintable;
        boolean canCopy = ismaintable;

        JSONObject tableObj = new JSONObject(true);
        tableObj.put("actionADD", canAdd&&ismaintable);
        tableObj.put("actionMODIFY", canModify);
        tableObj.put("actionDELETE", canDelete);
        tableObj.put("actionSUBMIT", canSubmit);
        tableObj.put("actionUNSUBMIT", canUNsubmit);
        tableObj.put("actionGROUPSUBMIT", canSubmit && table.isActionEnabled(Table.GROUPSUBMIT));
        tableObj.put("actionVOID", canVoid);
        tableObj.put("actionCANCOPY", canCopy);
        tableObj.put("actionIMPORT", canAdd&&!ismaintable);   //明细新增控件actionIMPORT判断
        tableObj.put("actionEXPORT", canExport&&!ismaintable); 


        return tableObj;

    }


    public JSONObject getWebActionforTableId(QuerySession qsession, Table table) throws Exception {

        JSONArray waObjButtons = new JSONArray();
        JSONArray waObjMenuItems = new JSONArray();

        HashMap actionEnv = new HashMap();
        actionEnv.put("maintable", table.getId());
        actionEnv.put("querySession", qsession);

        List<WebAction> was = table.getWebActions(WebAction.DisplayTypeEnum.ObjButton);
        for (int wasi = 0; wasi < was.size(); wasi++) {
            WebAction wa = was.get(wasi);
            if (wa.canDisplay(actionEnv)) {
                waObjButtons.add(wa.toObj(qsession.getLocale(), actionEnv));
            }
        }

        was = table.getWebActions(WebAction.DisplayTypeEnum.ListMenuItem);
        for (int wasi = 0; wasi < was.size(); wasi++) {
            WebAction wa = was.get(wasi);
            if (wa.canDisplay(actionEnv)) {
                waObjMenuItems.add(wa.toObj(qsession.getLocale(), actionEnv));
            }
        }

        JSONObject WebAction = new JSONObject();
        WebAction.put("objbutton", waObjButtons);
        WebAction.put("objmenu", waObjMenuItems);

        return WebAction;
    }


    public JSONArray getReftables(QuerySession qsession, Table table) throws Exception {
        JSONArray reftabs = new JSONArray();
        ArrayList rbts = table.getRefByTables();
        for (int i = 0; i < rbts.size(); i++) {
            RefByTable rbt = (RefByTable) rbts.get(i);
            Table rbtt = qsession.getTableManager().getTable(rbt.getTableId());
            //判断明细是否用户是否有权限
            if(!qsession.getUser().isAdmin()&&!SecurityWebUtils.isPermissionEnabled(rbtt.getSecurityDirectory(qsession.getTableManager()), qsession.getUser().getId(), Directory.READ)){
               continue; 
            }
            
            JSONObject reftabObj = new JSONObject();
            reftabObj.put("tableid", rbtt.getId());
            reftabObj.put("tablename", rbtt.getName());
            reftabObj.put("tabledesc", rbtt.getDescription(qsession.getLocale()));
            reftabObj.put("tabrelation", (rbt.getAssociationType() == RefByTable.ONE_TO_MANY ? "1:m" : "1:1"));
            reftabObj.put("tabinlinemode", rbt.getInlineMode());
            reftabObj.put("refcolid", rbt.getRefByColumnId());
            reftabs.add(reftabObj);
        }
        

        return reftabs;

    }

    public JSONArray getColumnbyHr(QuerySession qsession, Table table, int[] columnMasks, long objid,int refcolid) throws Exception {

        //JSONObject tabObj = new JSONObject();
        JSONArray cols = new JSONArray();

        PairTable hrtables = table.getGroupByHr();

        int securityGrade = qsession.getUser().getSecurityGrade();
        
        QueryResult result = null;
        QueryRequestImpl query=null;
        
        JSONObject objdata=null;
        if( objid != -1){
            query= new com.jackrain.nea.core.db.QueryRequestImpl(qsession);
            query.setMainTable(table.getId());
            query.addAllShowableColumnsToSelection(Column.MODIFY);
            if(refcolid<0) {
                query.addParam(table.getPrimaryKey().getId(), "" + objid);
            }else{
                query.addParam(refcolid, "" + objid);
            }
            result=QueryEngine.getInstance().doQuery(query);
            if(result.getRowCount()>1){
                throw new NDSException(Resources.getMessage("数据错误返回多条！",qsession.getLocale()));
            }
            objdata=result.getColumnObjbyid();
            log.debug(objdata.toJSONString());
        }
        
        
        for (Iterator it = hrtables.keys(); it.hasNext(); ) {
            
            Integer key = (Integer) it.next();
            
            if (hrtables.get(key) instanceof ColumnImpl) {
                Column col = (Column) hrtables.get(key);
                if (col.getSecurityGrade() > securityGrade) {
                    continue;
                }
                for (int j = 0; j < columnMasks.length; j++) {
                    if (col.isMaskSet(columnMasks[j])) {
                        JSONObject hrObj = new JSONObject();
                        hrObj.put("child",getColumnObject(col, qsession, true,objdata));
                        hrObj.put("size",1);
                        cols.add(hrObj);
                        break;
                    }
                }
            }
            
            
            if (hrtables.get(key) instanceof ArrayList) {

                JSONArray  jhrs= new JSONArray();
                
                ArrayList hrcols = (ArrayList) hrtables.get(key);
                Column hrcol=table.getColumn(key);
                
                if(hrcol==null){
                    throw new NDSException("ad_column id:"+key+" is invaild");
                }
                for (int i = 0; i < hrcols.size(); i++) {
                    Column col = (Column) hrcols.get(i);
                    if (col.getSecurityGrade() > securityGrade) {
                        continue;
                    }
                    for (int j = 0; j < columnMasks.length; j++) {
                        if (col.isMaskSet(columnMasks[j])) {
                            jhrs.add(getColumnObject(col, qsession, true,objdata));
                            break;
                        }
                    }
                }
                //if(jhrs.size()>0) {
                    JSONObject hrObj = new JSONObject();
                    if(jhrs.size()>0&&hrcol.isShowable(Column.MODIFY)) {
                        hrObj.put("childs", jhrs);
                        hrObj.put("size", jhrs.size());
                        hrObj.put("parentname", hrcol.getName());
                        hrObj.put("parentdesc", hrcol.getDescription(qsession.getLocale()));
                        JSONObject jor = hrcol.getJSONProps();
                        //支持hr收缩模式
                        if (jor != null && jor.containsKey("hrdisplay")) {

                            String fkdisplay = jor.getString("hrdisplay");

                            hrObj.put("hrdisplay", fkdisplay);

                        }else{
                            hrObj.put("hrdisplay", "expand"); 
                        }
                        
                    }else if(hrcol.isShowable(Column.MODIFY)){
                        hrObj.put("child",getColumnObject(table.getColumn(key), qsession, true,objdata));
                        hrObj.put("size",1);
                    }
                  
                //}
                     if(!hrObj.isEmpty()){
                         cols.add(hrObj);
                     }
            }


        }

        return cols;

    }


    public JSONObject getColumnObject(Column col, QuerySession querySession, Boolean includetype, JSONObject objdata) {

        JSONObject selectojb = new JSONObject();
        String column = col.getName();
        Column col2;
        Table refTable = col.getReferenceTable();
        String pdesc = col.getDescription(querySession.getLocale());
        TableManager tm = querySession.getTableManager();

        if (includetype) {
            int type;
            if (refTable != null) {
                col2 = refTable.getAlternateKey();
                type = col2.getType();
                selectojb.put("isfk", true);
                selectojb.put("reftable", col2.getTable().getName());
                selectojb.put("reftableid", col2.getTable().getId());
                ColumnLink columnLink = col.getColumnLink(tm);
                columnLink.addColumn(col2,tm);
                selectojb.put("inputname",columnLink.toHTMLString());
                selectojb.put("fkdisplay",Tools.nvl(col.getFkdisplay(),"drp"));
                
            } else {
                type = col.getType();
            }

//            if (type == Column.NUMBER) {
//                selectojb.put("type", "NUMBER");
//            } else {
//                selectojb.put("type", "STRING");
//            }

            PairTable values = col.getValues(querySession.getLocale());
            
            String defval = QueryUtils.replaceVariables(col.getDefaultValue(), querySession);

            DisplaySetting coldis=col.getDisplaySetting();
            
            if (values != null) {
                JSONArray combobox = new JSONArray();
                Iterator i1 = values.keys();
                Iterator i2 = values.values();
                while (i1.hasNext() && i2.hasNext()) {
                    JSONObject groupval = new JSONObject();
                    String limitdesc = String.valueOf(i2.next());
                    String limitval = String.valueOf(i1.next());
                    // add = so will match identically
                    //o.put(tmp1,"="+tmp2); // tmp1 is limit-description, tmp2 is limit-value
                    groupval.put("limitdesc", limitdesc);
                    groupval.put("limitval", limitval);
                    if(coldis.getObjectType()==5){
                        groupval.put("limitdis", Tools.getBoolean(limitval,false));
                    }
                    combobox.add(groupval);
                }
                selectojb.put("combobox", combobox);
                //defval= String.valueOf(values.get(defval));
            }

            JSONObject jor = col.getJSONProps();
            
            if (type == Column.DATE) {
                selectojb.put("display", "OBJ_DATE");

                //支持datelimit字段下来或弹出方式
                if (jor != null && jor.containsKey("datelimit")) {

                    String datelimit=jor.getString("datelimit");

                    selectojb.put("datelimit", datelimit);

                }
                
            } else if (type == Column.DATENUMBER) {
                selectojb.put("display", "OBJ_DATENUMBER");
                
                //支持datelimit字段下来或弹出方式
                if (jor != null && jor.containsKey("datelimit")) {

                    String datelimit=jor.getString("datelimit");

                    selectojb.put("datelimit",datelimit);

                }
            }else{
                selectojb.put("display", coldis.getObjectTypeString());

            }
            
            if(!selectojb.containsKey("datelimit")){
                selectojb.put("datelimit", "all");
            }
            
            selectojb.put("name", pdesc);
            selectojb.put("colname", column);
            selectojb.put("col", col.getDisplaySetting().getColumns());
            selectojb.put("row", col.getDisplaySetting().getRows());
            selectojb.put("statsize", col.getStatSize());
            selectojb.put("colid", col.getId());
            selectojb.put("isnotnull",!col.isNullable());


  
            
            String ptype="STRING";

            if(type==Column.DATENUMBER||type==Column.NUMBER){
                ptype="NUMBER";
                selectojb.put("scale",Tools.getInt(col.getScale(),0));
            }

            selectojb.put("type",ptype);

            String valuedata=null;
            
            if(objdata!=null) {
                if(col.isComputed()) {
                    ColumnInterpreter columnInterpreter=tm.getColumnInterpreter(col.getId());
                    valuedata=columnInterpreter.parseValue(objdata,querySession.getLocale(),col);
                    if (valuedata != null) {
                        selectojb.put("valuedata", valuedata);
                    }
                }else{
                    valuedata = objdata.getString(column);
                    if (valuedata != null) {
                        selectojb.put("valuedata", valuedata);
                    }
                }
                selectojb.put("readonly", !col.isModifiable(Column.MODIFY));
            } else{
                selectojb.put("readonly", !col.isModifiable(Column.ADD));
            }

            if (Validator.isNotNull(defval)&&objdata==null) {
                selectojb.put("defval", defval);
            }


        }

        return selectojb;

    }



//    public JSONObject getColumnObject(Column col, QuerySession querySession, Boolean includetype) {
//        
//        JSONObject selectojb = new JSONObject();
//        String column = col.getName();
//        Column col2;
//        Table refTable = col.getReferenceTable();
//        String pdesc = col.getDescription(querySession.getLocale());
//        TableManager tm = querySession.getTableManager();
//
//        if (includetype) {
//            int type;
//            if (refTable != null) {
//                col2 = refTable.getAlternateKey();
//                type = col2.getType();
//                selectojb.put("isfk", true);
//                selectojb.put("reftable", col2.getTable().getName());
//                selectojb.put("reftableid", col2.getTable().getId());
//                ColumnLink columnLink = col.getColumnLink(tm);
//                columnLink.addColumn(col2,tm);
//                selectojb.put("inputname",columnLink.toHTMLString());
//                selectojb.put("fkdisplay",col.getFkdisplay());
//            } else {
//                type = col.getType();
//            }
//            
//            PairTable values = col.getValues(querySession.getLocale());
//            String defval = QueryUtils.replaceVariables(col.getDefaultValue(), querySession);
//
//            DisplaySetting coldis=col.getDisplaySetting();
//
//            if (values != null) {
//                JSONArray combobox = new JSONArray();
//                Iterator i1 = values.keys();
//                Iterator i2 = values.values();
//                while (i1.hasNext() && i2.hasNext()) {
//                    JSONObject groupval = new JSONObject();
//                    String limitdesc = String.valueOf(i2.next());
//                    String limitval = String.valueOf(i1.next());
//                    // add = so will match identically
//                    //o.put(tmp1,"="+tmp2); // tmp1 is limit-description, tmp2 is limit-value
//                    groupval.put("limitdesc", limitdesc);
//                    groupval.put("limitval", limitval);
//                    if(coldis.getObjectType()==5){
//                        groupval.put("limitdis", Tools.getBoolean(limitval,false));
//                    }
//                    combobox.add(groupval);
//                }
//                selectojb.put("combobox", combobox);
//                defval= String.valueOf(values.get(defval));
//            }
//            
//                if (type == Column.DATE) {
//                    selectojb.put("display", "OBJ_DATE");
//                } else if (type == Column.DATENUMBER) {
//                    selectojb.put("display", "OBJ_DATENUMBER");
//                }else{
//                    selectojb.put("display", coldis.getObjectTypeString());
//                    
//                }
//                
//                String ptype="STRING";
//                
//                if(type==Column.DATENUMBER||type==Column.NUMBER){
//                    ptype="NUMBER";
//                    selectojb.put("scale",Tools.getInt(col.getScale(),0));
//                }
//            
//                selectojb.put("name", pdesc);
//                selectojb.put("colname", column);
//                selectojb.put("colid", col.getId());
//                selectojb.put("isnotnull",!col.isNullable());
//                selectojb.put("type",ptype);
//            
//
//        }
//
//        return selectojb;
//
//    }
//

}
